package view;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;

import javax.swing.JPanel;

import roles.Role;
import typesEnum.Sexe;
import model.Case;
import model.Fourmiliere;
import model.Terrain;
import etresVivant.Fourmi;

public class Renderer extends JPanel {
	private static final long serialVersionUID = 1L;
	
	private int nbLignes, nbCol; // dimensions du terrain

	/* --- Tailles des entites (px) --- */
	private int szCase;
	private int margin;
	private int szFourmiliere 	= 30;
	private int szReine 		= 10;
	private int szFourmi 		= 3;
	private int szSexue 		= 6;
	private int szPheromones 	= 5;
	private int szProie 		= 10;

	/* --- Couleurs --- */
	class colAlpha extends Color {
		/**
		 * Extension de color afin de faire un setColor sur le canal Alpha
		 * sans avoir a bitshift les autres canaux
		 */
		private static final long serialVersionUID = 1L;
		int R;
		int G;
		int B;
		int A;
		
		public colAlpha(int _r, int _g, int _b, int _a ) {
			super(_r, _g, _b, _a);
			R = _r;
			G = _g;
			B = _b;
			A = _a;
		}

		/*
		 * Alpha [0-255]
		 */
		public Color setAlpha( int alpha ) {
			A = alpha;
//			System.out.println(A);
			return new Color(R, G, B, A );
		}
	}

	private Color colBckgrd 		= Color.WHITE; // jour
//	private Color colBckgrd 		= Color.BLACK; // nuit
	private Color colGrille 		= Color.ORANGE; // jour
//	private Color colGrille 		= Color.CYAN; // nuit
	
	private Color 		colFourmiliere 	= Color.BLACK; // jour
//	private Color 		colFourmiliere 	= Color.WHITE; // nuit
	private Color 		colOuvriere 	= Color.BLACK; // jour
//	private Color 		colOuvriere 	= Color.WHITE; // nuit
	private Color 		colSexueMale 	= Color.BLUE;
	private Color 		colSexueFemelle	= Color.RED;
	private Color 		colReine	 	= Color.YELLOW;
	private Color		colProie 		= Color.MAGENTA;
	
	private colAlpha 	colPheroChasse = new colAlpha( // GREEN
		Color.GREEN.getRed(),
		Color.GREEN.getGreen(),
		Color.GREEN.getBlue(),
		Color.GREEN.getAlpha() );
	private colAlpha 	colPheroReprod	= new colAlpha( // RED
		Color.RED.getRed(),
		Color.RED.getGreen(),
		Color.RED.getBlue(),
		Color.RED.getAlpha() );
	
	/*
	 * Pause de 50ms
	 */
	private void pause() {
		try { Thread.sleep(50); } catch (InterruptedException e) {}
	}
	
	/*
	 * Thread graphique charge de Repaint() la fenetre
	 */
	public class ThreadDrawer extends Thread {
		@Override
		public void run() {
			
			/* --- Attente du model --- */
			System.out.println("...waiting for Model's data (View)");
			while ( !Terrain.isAvailable() ) {
				pause();
			}
			
			/* --- Vue des donnees du Model --- */
			// recup des dimensions du terrain
			nbLignes 	= Terrain.getNbLine();
			nbCol 		= Terrain.getNbColumn();
			System.out.println("....starting View of the Model");
			while ( Terrain.isAvailable() ) {				
				repaint();
				pause(); // une pitite pause pour eviter les stutters dûs aux calculs de l'autre thread
			}
			
			// Fin de l'affichage graphique
			System.out.println("...shutdown View.");
		}
	}

	/*
	 * Lance le thread graphique
	 */
	public Renderer(int sizeCase, int _margin) {
		szCase = sizeCase;
		margin = _margin;
		szPheromones = szCase;
		new ThreadDrawer().start();
	}

	@Override
	public void paint(Graphics g) { // main thread
		// attente modele
		while (!Terrain.isAvailable() ) { pause(); }
		
		/* --- Background --- */
		g.setColor( colBckgrd );
		g.fillRect(0, 0, getWidth(), getHeight() );
		
		/* --- Terrain --- */
		int x = margin, y = margin;
		g.setColor( colGrille );
		for (int i = 0; i < nbLignes-1; i++) { 	// Y
			for (int j = 0; j < nbCol-1; j++) {	// X
				g.drawRect(x, y, szCase, szCase);
				x = x + szCase; // increment pour mettre a l'echelle de la grille
			}
			x = margin;
			y = y + szCase; // increment pour mettre a l'echelle de la grille
		}
		
		/* --- Pheromones et Proies --- */
		for (y = 0; y < Terrain.getNbLine(); y++) { 		// Y
			for (x = 0; x < Terrain.getNbColumn(); x++) { 	// X
				Case c = Terrain.getCase(x, y);
				
				// Proies
				if ( c.isProie() ) {
					g.setColor(colProie);
					g.fillOval(
							/* coord   + marge  - recentrage de l'entite par rapport a sa taille */
							x * szCase + margin - (szProie / 2),
							y * szCase + margin - (szProie / 2),
							szProie, szProie);
				}
				
				// Pheromones
				int max;
				if ( ( max = c.maxPheromone() ) > 0 ) { // il y en a
					// pheromone chasse
					if ( c.getPheromoneChasse() > c.getPheromoneReproduction() ) {
						max = max / 100 * 255 / 100;
						g.setColor( colPheroChasse.setAlpha(max) );
					}
					// pheromone reprod
					if ( c.getPheromoneReproduction() > c.getPheromoneChasse() ) {
						max = max / 100 * 150 / 100;
						g.setColor( colPheroReprod.setAlpha(max) );
					}				

					// Dessine pheromone
					g.fillRect(
							x * szCase + margin - (szPheromones / 2),
							y * szCase + margin - (szPheromones / 2),
							szPheromones, szPheromones);					
				}
			}
		}

		/* --- Fourmilieres --- */
		// pour chaque Fourmiliere du Terrain
		for (Fourmiliere fourmiliere : Terrain.fourmilieres) {
			
			/* --- Fourmis --- */			
			// pour chaque Fourmi de la Fourmiliere
			ArrayList<Fourmi> fourmis = fourmiliere.getFourmis(); // ! acces conccurrent
			if (fourmis.size() != 0 && fourmis != null ) { // si on en a, on les affiche
				for (Fourmi f : fourmis) {
//					if ( f != null ) { // hack bidon pour ne pas lire dans une liste mal synchro :3
//						f.printCase();
                        Role role = f.getRole();
                        
                        // Ouvriere
						if ( role.monRole().equals("Ouvriere") ) {
							g.setColor( colOuvriere );
							
							g.fillRect( // dessine ouvriere								
									f.getCase().getX() * szCase + margin - (szFourmi / 2),
									f.getCase().getY() * szCase + margin - (szFourmi / 2),
									szFourmi, szFourmi);
						}
						
						// Sexuees
						else if (role.monRole().equals("Sexue") ) {
							if ( f.getSexe() == Sexe.FEMELLE ) {
								g.setColor( colSexueFemelle );
							}
							if ( f.getSexe() == Sexe.MALE ) {
								g.setColor( colSexueMale );
							}
							
							g.fillRect( // dessine sexuee								
									f.getCase().getX() * szCase + margin - (szFourmi / 2),
									f.getCase().getY() * szCase + margin - (szFourmi / 2),
									szSexue, szSexue);
						}
//					}
				}
			}

			// dessine fourmiliere
			g.setColor(colFourmiliere);
			g.fillOval(
					// position - recentrage + marge exterieure
					fourmiliere.getCase().getX() * szCase - (szFourmiliere / 2)	+ margin,
					fourmiliere.getCase().getY() * szCase - (szFourmiliere / 2) + margin,
					szFourmiliere, szFourmiliere);
			
			// Reine
			g.setColor( colReine );
			g.fillOval( // dessine reine								
					fourmiliere.getFourmiReine().getCase().getX() * szCase + margin - (szReine / 2),
					fourmiliere.getFourmiReine().getCase().getY() * szCase + margin - (szReine / 2),
					szReine, szReine);
		}
	}
}
